package business.GUIMemento;

import business.adapter.TextChanges.TextChangesAdapterSingleton;
import java.util.Stack;
import models.TextChanges;

/**
 *
 * @author Jordan
 */
public class MementoTextChanges {

    private final Stack<TextChanges> stackOfChanges;
    private boolean changeFromMemento;
    private final StringBuilder txtBack;
    
    private static MementoTextChanges instance;

    /**
     * Memento with the stack of changes in the text
     *
     * @param txtBack pointer to text back
     */
    private MementoTextChanges(StringBuilder txtBack) {
        this.stackOfChanges = new Stack<>();
        this.txtBack = txtBack;
        this.changeFromMemento = false;
    }
    public static MementoTextChanges getInstance(StringBuilder txtBack)
    {
        if(instance == null)
            instance = new MementoTextChanges(txtBack);
        return instance;
    }
    public static MementoTextChanges getInstanceOnly()
    {
        return instance;
    }

    /**
     * Put an TextChange in the stack, if server refuse changes, back to what
     * its have before
     *
     * @param txtc The new TextChanges
     */
    public void pushAndSend(TextChanges txtc) {
        txtc.getChanges();
        stackOfChanges.push(txtc);
        if (sendToServer(txtc)) {
            return;
        }
        changeTxtArea(stackOfChanges.pop().invert()); //inverte (add vira remover e vice versa)
    }

    /**
     * Remove and back text area, if server refuse changes, back to what its
     * have before
     */
    public void popAndSend() {
        TextChanges tc = stackOfChanges.pop().invert();
        changeTxtArea(tc);
        if (sendToServer(tc)) {
            return;
        }
        stackOfChanges.add(tc);
    }

    public boolean isEmpty() {
        return this.stackOfChanges.empty();
    }

    /**
     * Change de JTextArea of the Windows
     *
     * @param tc the textChange object that will be changed
     */
    private void changeTxtArea(final TextChanges tc) {

        tc.getChanges();
        changeFromMemento = true;
        TextChangesAdapterSingleton.getInstance().changeTextArea(tc);
        changeFromMemento = false;
        if (tc.isType()) {
            txtBack.insert(tc.getOffset(), tc.getText());
        } else {
            txtBack.delete(tc.getOffset(), tc.getOffset() + tc.getSize()); //backup
        }
        
    }

    private boolean sendToServer(TextChanges txtc) {

        //falta implementar, por enquanto, testando quando o server recusa
        return true;
    }

    public boolean getChangeFromMemento() {
        return this.changeFromMemento;
    }

}
